import cloud from '@lafjs/cloud'
import Pay from 'wechatpay-node-v3-laf';
const db = cloud.mongo.db

let userId //用户id
let orderParams = {}//前端传来的订单参数
let out_trade_no = '' //订单号
let balance_out_trade_no = '' //尾款订单号订单号
let appid

export default async function (ctx: FunctionContext) {
  await variablesInit()//初始化全局变量

  orderParams = ctx.body //获取前端传来的订单参数
  out_trade_no = generateOrderNumber() //生成订单号


  if (cloud.utils.isString(ctx.user.uid)) {
    userId = ctx.user.uid
  } else {
    userId = ctx.user.uid._id
  }
  let res = await cloud.nw.db.findByWhereJson({
    dbName: "web-users",
    whereJson: { _id: userId },
  });

  //判断是否重复报名
  let isRepeat = await isRepeatSignUp()
  if (isRepeat) return cloud.utils.requestReturn({ code: 500, msg: isRepeat })

  if (ctx.body.payType == "MP-WEIXIN") {
    appid = "wx9c3827b9e4e2ea96"
  } else {
    appid = "wx267097d752f5c3fd"
  }

  const pay = new Pay({
    appid, // 认证服务号 appid
    mchid: '1593154581',  //  绑定该认证服务号的微信支付商户号
    publicKey: savePublicKey(), // V3 公钥 apiclient_cert.pem
    privateKey: getPrivateKey(), // V3 秘钥 apiclient_key.pem
  });

  //如果有传上一笔订单号
  if (orderParams.hasOwnProperty('out_trade_no')) {
    const result = await pay.query({ out_trade_no: orderParams['out_trade_no'] });
    if (result.trade_state == "SUCCESS" && result.transaction_id) {
      return cloud.utils.requestReturn({ code: 500, msg: "该订单已支付成功，请勿重复支付" })
    }
  }

  //判断该身份证号是否有在别的账号上用到
  if (orderParams["approvalContent"].model.identityCard) {
    let allUsers = await db.collection("web-users").find({ "baseInfo.identityCard": orderParams["approvalContent"].model.identityCard }).project({ _id: 1 }).toArray()
    if (allUsers.length > 1) return cloud.utils.requestReturn({ code: 500, msg: "该身份证号码已关联其他手机号码" })
    if (allUsers[0]._id != userId) return cloud.utils.requestReturn({ code: 500, msg: "该身份证号码已关联其他手机号码" })
  }

  //设置支付金额
  let total = (orderParams["price"] * 100)
  //如果有预付款字段
  if (orderParams["signUpPrice"]) total = (orderParams["signUpPrice"] * 100)
  //如果有尾款字段
  if (orderParams["balancePay"]) {
    total = (orderParams["balancePay"] * 100)
    balance_out_trade_no = generateOrderNumber()
  }

  const params = {
    description: '商品下单',
    out_trade_no: balance_out_trade_no ? balance_out_trade_no : out_trade_no, //订单号
    notify_url: 'https://p9hiw73hs7.gzg.sealos.run/web/wechat_noauth',
    amount: { total },
    scene_info: {
      payer_client_ip: ctx.headers['x-real-ip'],
    },
  };

  switch (orderParams["payType"]) {
    case "MP-WEIXIN":
      params["payer"] = { openid: res.wx.openid }
      break;
    case "H5":
      params["payer"] = { openid: res.h5.openid }
      break;
    case "PC":
      break;
    default:
      break;
  }

  //如果支付金额为0，则直接返回成功
  if (params.amount.total == 0) {
    let orderId = await processOrders() //操作订单
    return cloud.utils.requestReturn({ data: orderId })
  }

  console.log('微信支付入参', params)
  if (orderParams["payType"] == "PC") {
    let result = await pay.transactions_native(params);
    if (result.status == 200) {
      let orderId = await processOrders() //操作订单
      console.log('PC-订单id', orderId)

      return cloud.utils.requestReturn({
        data: { url: result.code_url, orderId }
      })
    } else {
      wxPayrecordError('transactions_native', result)
      console.log('PC微信支付失败', result);
      console.log('PC微信支付失败', result.errRaw.config);
      return cloud.utils.requestReturn({ code: 500, msg: "" })
    }
  } else {
    let result = await pay.transactions_jsapi(params);
    console.log('H5微信支付', result);
    if (result.hasOwnProperty("errRaw")) {
      wxPayrecordError('transactions_jsapi', result)
      console.log('H5微信支付失败', result.errRaw.config);
      return cloud.utils.requestReturn({
        data: "",
        code: 500,
        msg: result.errRaw.message,
      });
    } else {
      let orderId = await processOrders() //操作订单
      console.log('移动-订单 id', orderId)

      result.debug = false;
      return cloud.utils.requestReturn({ data: result });
    }
  }
}

//记录微信支付报错
async function wxPayrecordError(type, resp) {
  let now = Date.now()
  await cloud.nw.db.add({
    dbName: "wx-pay-error",
    dataJson: {
      type,
      content: resp,
      timeStamp: now,
      timeUTC8_format: cloud.utils.dateTimeFormat(cloud.utils.getNowInUTC8(now), "all")
    },
    cancelAddTime: false,
  });
}

//全局变量初始化
function variablesInit() {
  userId = null //用户 id
  orderParams = {}//前端传来的订单参数
  out_trade_no = '' //订单号
  balance_out_trade_no = '' //尾款订单号订单号
  appid = null
}

//判断该课程是否是重复报名-判断该用户，在本年度，是否报名过该课程
async function isRepeatSignUp() {
  //如果是支付尾款
  if (orderParams["balancePay"]) return ""

  let year = cloud.utils.dateTimeFormat(new Date(), "year")
  let courseId = orderParams["curriculum_id"] || orderParams['curriculum_Info']._id

  let ret = await cloud.nw.db.findByWhereJson({
    dbName: "web-course",
    whereJson: { _id: courseId },
  });
  // console.log('课程信息', courseId, ret)

  let noAuth = false
  //该课程是否不校验报名次数
  if (ret && ret.hasOwnProperty("verifyRegistrations") && ret.verifyRegistrations == 1) noAuth = true
  if (noAuth) return ""

  let res = await db.collection("web-order")
    .find({
      curriculum_id: courseId,
      _add_time_str: { $regex: year.toString(), $options: "i" },
      userId,
      status: { $in: [1, 2, 7, 8, 9, 10] }
    })
    .toArray()

  let selectLesson = []
  if (res && res.length) {
    for (let index = 0; index < res.length; index++) {
      const element = res[index];
      selectLesson.push(...element.approvalContent.selectLesson)
    }
    let newSelectLesson = orderParams["approvalContent"]["selectLesson"]
    for (let index = 0; index < newSelectLesson.length; index++) {
      const element = newSelectLesson[index];
      if (cloud.utils.isFieldEqual(selectLesson, "tag", element.tag)) {
        return `该课程内容${element.name}已报名，请勿重复报名`
      }
    }
    return ""
  } else {
    return ""
  }
}

async function processOrders() {
  //如果传过来有尾款订单号
  if (orderParams.hasOwnProperty('balance_out_trade_no')) {
    return await updateBalanceOrder()
  }
  //如果传过来有支付尾款字段
  else if (orderParams.hasOwnProperty("balancePay")) {
    return updateBalance()
  }
  else if (orderParams.hasOwnProperty('out_trade_no')) {
    return await updateOrder()
  } else {
    return await addOrder()
  }
}

//给订单添加支付尾款单号
async function updateBalance() {
  await cloud.nw.db.update({
    dbName: "web-order",
    whereJson: { _id: orderParams['orderId'] }, //根据订单 id去查
    dataJson: { balance_out_trade_no },//更新单号
  });
  return orderParams['orderId']
}

//更新尾款单号
async function updateBalanceOrder() {
  await cloud.nw.db.update({
    dbName: "web-order",
    whereJson: { balance_out_trade_no: orderParams['balance_out_trade_no'] }, //根据旧单号去查
    dataJson: { balance_out_trade_no, _update_time: Date.now(), payType: orderParams["payType"] },//更新单号
  });

  let resp = await cloud.nw.db.findByWhereJson({
    dbName: "web-order",
    whereJson: { balance_out_trade_no },
  });
  return resp._id
}

async function updateOrder() {
  await cloud.nw.db.update({
    dbName: "web-order",
    whereJson: { out_trade_no: orderParams['out_trade_no'] }, //根据旧单号去查
    dataJson: { out_trade_no, _update_time: Date.now(), payType: orderParams["payType"] },//更新单号
  });

  let resp = await cloud.nw.db.findByWhereJson({
    dbName: "web-order",
    whereJson: { out_trade_no },
  });
  return resp._id
}

async function addOrder() {
  //status 0 待支付
  //status 1 待审核
  //status 2 审核通过
  //status 3 审核失败
  //status 4 退款成功
  //status 5 退款失败
  //status 6 取消订单
  //status 7 已开票
  //status 8 支付尾款
  //status 9 部分退款
  //status 10 优惠减免

  let dataJson = {
    ...orderParams,
    out_trade_no,
    userId,
    status: 0,
    exp_time: Date.now() + (2 * 60 * 60 * 1000)  //过期时间
  }
  return await cloud.nw.db.add({
    dbName: "web-order", dataJson, cancelAddTime: false
  });
}


function getPrivateKey() {
  const key = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCf2rhKEaSNKHVN
i4VWD7zpqNcM3O3NPdLyxAR4ie96eCzLzvxzpUY2Oy03yA6qoWfV6KnvaN2uqNWp
ng041W11MUZIR07bKyXauapfKz1X+5aJa5qrlsiNP3/rzSoqxCTtySKuoeTG2/u7
QpipTZ7L7Rzy/6pI2gbr53f7gxCErfyI2FsbzhSXnqOeUDMvq24EwtJCnYlSi3p7
LRv44qT6l0MNfZUY7pZX/0SJ7WdsUfZQOtxNpYvrRXYgvDg67Y67tcPv0e1kvs0F
y5rxk82sQEA3+avpHjfsn+0+TrzrS5hKKiOlERDfCZMV79MTeJA3yyEdIs24g9sb
DIm2L11zAgMBAAECggEAZ76GXiPHHImGX7ZN6cW7ABZAwyta9hnKnx2SHTy//Eak
I/2In/FCeQ280ff3dMvd3Njr+OGhBaqzSCq4QAtbx3QcPepxhhIhtitLJAqm/EPe
tf7s2bG5JNpyRfHYDPtRUDV6WcXd+SVp4WVeOHqUtZqEcDx3ImLFnTKTDttHzCMs
J53W0nLQI3mZ0ADeua1DpEF3a2IrGTKRqIBxTHGlm5qniYCvpHImv+dTrcykq+Kx
0SSYLKYe3SstDsQUN+5jG0T1TIxm1Gwb9UW7AuK29YbTuE2T7Qa/T0AztAYZpbqK
5x7CnVhxFjFqugk2EpmE8/4nUBuXMuTP26KSyFLZ2QKBgQDNVXtlkXrRat5Xi/nO
VpErTTDwQbrMHsYQsh2EAYEQfnBLCDJ1V6dFx0IHrK3wkb4zMvkm2rWAwxdn81N+
mNzAwQU893Lh+Lv9x3DW70PvgE3XrvjqzGQW+f5eaiJlCjKgYJOC2pbcZCs+gXma
bc5xhIQUsxjzRSj1zl1bAVky5wKBgQDHTGO6S4VLKoaXuBAEX+IEvN8vWL7T4pW1
aXHb0UzZy+46bP87PghbNmCuqwM5h9DTQ4vRKhJV/+tmtYZR529x4wXlL7LJ6GED
rv5Iw2LxSshlLo/TwtHBt6rTxf//klh+XqUnNyXAd/0KAOp7GK/0c2w/y61Mrfd0
IuejBXq7lQKBgH4jeT6X9F8Zy6T0dG1xeJSlQt8VQe+LKBmxkbg6RFMhmVI+ouC7
DCMtmT6lseULY1CIi852pPGI56QQMsaemV5ANTuSt5xh9PqdvpALRCypISjScE+t
Z/9FbCIMCT0Q2rDzIytLpUmWr4oid9WKhzvtMEaXD0jCv7rhHzB8z5MZAoGAebgj
6HGbVQ8B6MOXtLRCvBYGUUpoMcxfFs7xpQktYI92TeSn9Syrudl6LvNvIsHaPk0w
pWyGilOlF7Oh93/bxriaryD0lu//4FoOH66FTU0ZGwLXAMQpi6B7CqAQ+6wLtBJl
14+M1QHzXxq0Gr43KJsd79CbZQuS6DExO5VrIgkCgYEAko7Lid52kjrDqLx2cSKc
Dsl8J2rBgzoFMD1E5bArbaBSt9zQ2DpS4PvkQYQxQ4SSg5v6CxYpcxLdpCA+fabI
eJpNNfuc3XxH5AOiO0u7s9pv+66aVbZP5t8NLI+PgnRwk4QPXLiO4soXgU6FEhsP
dv9KAEr9NLYadg0rMl09elc=
-----END PRIVATE KEY-----
`;
  return key;
}

function savePublicKey() {
  return `
-----BEGIN CERTIFICATE-----
MIIEKDCCAxCgAwIBAgIUNLJk3hYaWOL+VX9SbvbOxXRrZ3owDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjMwNzE5MDk0NjQ4WhcNMjgwNzE3MDk0NjQ4WjCBgTETMBEGA1UEAwwK
MTU5MzE1NDU4MTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQL
DCTkuIrmtbfkupror5rln7norq3lrabmoKHmnInpmZDlhazlj7gxCzAJBgNVBAYM
AkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAJ/auEoRpI0odU2LhVYPvOmo1wzc7c090vLEBHiJ73p4LMvO/HOlRjY7
LTfIDqqhZ9Xoqe9o3a6o1ameDTjVbXUxRkhHTtsrJdq5ql8rPVf7lolrmquWyI0/
f+vNKirEJO3JIq6h5Mbb+7tCmKlNnsvtHPL/qkjaBuvnd/uDEISt/IjYWxvOFJee
o55QMy+rbgTC0kKdiVKLenstG/jipPqXQw19lRjullf/RIntZ2xR9lA63E2li+tF
diC8ODrtjru1w+/R7WS+zQXLmvGTzaxAQDf5q+keN+yf7T5OvOtLmEoqI6UREN8J
kxXv0xN4kDfLIR0izbiD2xsMibYvXXMCAwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsG
A1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2Y2Eu
aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRC
MDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdB
OUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQAr6mQ7
8LJ1QvvTjMuMJ11UrgKf5wSawuJiL6MfetVBB51JwGKBfBJ/KgBsWrms+Eg38lZZ
QKDgwkLE/PfqEzB9NSjQkZvmpOfx6+KAXBAYrMngDwATIESgJAPFo4g/cowDpvaC
noNWvNHIZCR2whi29Zy8xoKONme944rYEYWFm1M06scglWuo2mo4Wk6/SiAVh6JO
91XJM0P+SxZV7CQ5K8aIpqUcppRk54MDujrLJB8lRVHUNWhcRzj7H6cMmfoY/H+a
CsocVeEBcwhbffZLaYhr7He60D3O2ADTZFRNr73dDb4zEDRrxhRjKHQDO7enUzc0
Vgj5ab17makmBtvs
-----END CERTIFICATE-----
`
}

// 生成订单号
function generateOrderNumber() {
  const timestamp = Date.now().toString(); // 获取当前时间戳
  const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); // 生成3位随机数
  return timestamp + random; // 拼接时间戳和随机数作为订单号
}
